package model.storage;


import model.Circle;
import model.Shape;
import model.ShapeType;
import model.Square;
import model.validation.CircleValidator;
import model.validation.ShapeValidator;
import model.validation.SquareValidator;

import java.util.List;

public class GeneralStorage {

    private final SimpleShapeStorage<Circle> circleSimpleShapeStorage;
    private final SimpleShapeStorage<Square> squareSimpleShapeStorage;

    public GeneralStorage() {
        circleSimpleShapeStorage = new SimpleShapeStorage<Circle>();
        squareSimpleShapeStorage = new SimpleShapeStorage<Square>();
    }

    private <T extends Shape> IShapeStorage<T> getStorageForShapeType(T shape) {
        switch (shape.getShapeType()) {
            case CIRCLE:
                return (IShapeStorage<T>) circleSimpleShapeStorage;
            case SQUARE:
                return (IShapeStorage<T>) squareSimpleShapeStorage;
            default:
                throw new RuntimeException("unexpected shape type");
        }
    }

    public ShapeValidator getShapeValidator(final ShapeType shapeType) {
        switch (shapeType) {
            case CIRCLE:
                return new CircleValidator();
            case SQUARE:
                return new SquareValidator();
            default:
                throw new RuntimeException("unexpected shape");
        }
    }

    public <T extends Shape> void addShape(final T shape) {
        final ShapeType shapeType = shape.getShapeType();
        getShapeValidator(shapeType).validate(shape);
        final IShapeStorage<T> storage = getStorageForShapeType(shape);
        storage.add(shape);
    }

    public <T extends Shape> void removeShape(final T shape) {
        final IShapeStorage storage = getStorageForShapeType(shape);
        storage.remove(shape);
    }

    public List getAllForShapeType(final ShapeType shapeType) {
        switch (shapeType) {
            case CIRCLE:
                return circleSimpleShapeStorage.getAll();
            case SQUARE:
                return squareSimpleShapeStorage.getAll();
            default:
                throw new RuntimeException();
        }
    }

    public <T extends Shape> void editShape(final Shape shape) {
        final ShapeType shapeType = shape.getShapeType();
        getShapeValidator(shapeType).validate(shape);
        final IShapeStorage storage = getStorageForShapeType(shape);
        storage.edit(shape);

    }

    public void clear() {
        squareSimpleShapeStorage.clear();
        circleSimpleShapeStorage.clear();
    }
}
